package com.zhiche.wms.service.movement.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.zhiche.wms.core.supports.BaseException;
import com.zhiche.wms.core.utils.SnowFlakeId;
import com.zhiche.wms.domain.mapper.movement.MovementHeaderMapper;
import com.zhiche.wms.domain.model.movement.MovementHeader;
import com.zhiche.wms.domain.model.movement.MovementLine;
import com.zhiche.wms.domain.model.stock.StockProperty;
import com.zhiche.wms.service.constant.Status;
import com.zhiche.wms.service.movement.IMovementHeaderService;
import com.zhiche.wms.service.stock.impl.StockServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 移位单头 服务实现类
 * </p>
 *
 * @author zhaoguixin
 * @since 2018-05-30
 */
@Service
public class MovementHeaderServiceImpl extends ServiceImpl<MovementHeaderMapper, MovementHeader> implements IMovementHeaderService {

    @Autowired
    private SnowFlakeId snowFlakeId;

    @Autowired
    private MovementLineServiceImpl movementLineService;

    @Autowired
    private StockServiceImpl stockService;

    @Override
    @Transactional
    public boolean creatMovement(MovementHeader movementHeader) {
        movementHeader.setId(snowFlakeId.nextId());
        for (MovementLine ml : movementHeader.getMovementLineList()) {
            ml.setId(snowFlakeId.nextId());
            ml.setHeaderId(movementHeader.getId());
            movementLineService.insert(ml);
        }
//        movementHeader.setStatus(Long.toString(snowFlakeId.nextId()));
        movementHeader.setLineCount(movementHeader.getMovementLineList().size());
        movementHeader.setStatus(Status.SAVE);
        return insert(movementHeader);
    }

    @Override
    @Transactional
    public boolean auditMovement(Long movementId) {

        MovementHeader movementHeader = selectById(movementId);
        if (Objects.isNull(movementHeader)) throw new BaseException(3010, "移位单不存在！");

        EntityWrapper<MovementLine> ew = new EntityWrapper<>();
        ew.eq("header_id", movementHeader.getId());
        List<MovementLine> movementLineList = movementLineService.selectList(ew);
        if (Objects.isNull(movementHeader)) throw new BaseException(3020, "移位单明细不存在！");

        for (MovementLine ml : movementLineList) {
            updateStockQty(movementHeader.getStoreHouseId(), ml);
        }
        movementHeader.setStatus("20");
        movementHeader.setGmtCreate(null);//创建时间使用数据库自行处理
        movementHeader.setGmtModified(null);//更新时间使用数据库自行处理
        return updateById(movementHeader);
    }

    @Override
    public boolean createAndAuditMovenment(MovementHeader movementHeader) {

        movementHeader.setId(snowFlakeId.nextId());
        for (MovementLine ml : movementHeader.getMovementLineList()) {
            ml.setId(snowFlakeId.nextId());
            ml.setHeaderId(movementHeader.getId());

            if (movementLineService.insert(ml)) {
                updateStockQty(movementHeader.getStoreHouseId(), ml);
            } else {
                throw new BaseException("保存移位单明细失败！");
            }
        }

        movementHeader.setLineCount(movementHeader.getMovementLineList().size());
        movementHeader.setStatus(Status.AUDIT);
        return insert(movementHeader);
    }

    @Override
    public boolean cancelAuditMovement(Long movementId) {
        MovementHeader movementHeader = selectById(movementId);
        if (Objects.isNull(movementHeader)) throw new BaseException(3010, "移位单不存在！");

        EntityWrapper<MovementLine> ew = new EntityWrapper<>();
        ew.eq("header_id", movementHeader.getId());
        List<MovementLine> movementLineList = movementLineService.selectList(ew);
        if (Objects.isNull(movementHeader)) throw new BaseException(3020, "移位单明细不存在！");

        for (MovementLine ml : movementLineList) {
            cancelStockQty(movementHeader.getStoreHouseId(), ml);
        }
        movementHeader.setStatus(Status.CANCEL);
        movementHeader.setGmtCreate(null);//创建时间使用数据库自行处理
        movementHeader.setGmtModified(null);//更新时间使用数据库自行处理
        return updateById(movementHeader);
    }

    /**
     * 更新库存量
     *
     * @param storeHouseId 仓库ID
     */
    private boolean updateStockQty(Long storeHouseId, MovementLine ml) {
        StockProperty stockProperty = new StockProperty();
        BeanUtils.copyProperties(ml, stockProperty);
        stockProperty.setQty(ml.getQty());
        stockProperty.setStoreHouseId(storeHouseId);
        if (!Objects.isNull(ml.getDestinationLocationId())) {
            stockProperty.setLocationId(ml.getDestinationLocationId());//增加目标储位的库存
            stockService.addStock(stockProperty, "10", ml.getId());
        }

        if (!Objects.isNull(ml.getSourceLocationId())) {
            stockProperty.setLocationId(ml.getSourceLocationId());     //减少源储位的库存
            stockService.minusStock(stockProperty, "10", ml.getId());
        }

        return true;
    }

    /**
     * 更新库存量
     *
     * @param storeHouseId 仓库ID
     * @param ml
     * @return
     */
    private boolean cancelStockQty(Long storeHouseId, MovementLine ml) {
        StockProperty stockProperty = new StockProperty();
        BeanUtils.copyProperties(ml, stockProperty);
        stockProperty.setQty(ml.getQty());
        stockProperty.setStoreHouseId(storeHouseId);
        if (!Objects.isNull(ml.getDestinationLocationId())) {
            stockProperty.setLocationId(ml.getDestinationLocationId());//减少目标储位的库存
            stockService.minusStock(stockProperty, "15", ml.getId());
        }

        if (!Objects.isNull(ml.getSourceLocationId())) {
            stockProperty.setLocationId(ml.getSourceLocationId());     //减少源储位的库存
            stockService.addStock(stockProperty, "15", ml.getId());
        }

        return true;
    }

}
